package com.cy.stone.framework.log.aspect;

import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

@Aspect
@Component
@Slf4j
public class LogAspect {

    @Pointcut("(@within(org.springframework.stereotype.Controller)) " +
            "|| @within(org.springframework.web.bind.annotation.RestController)")
    public void logging(){
    }

    @Around(value = "logging()", argNames = "pjp")
    public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
        String className = pjp.getTarget().getClass().getName();
        MethodSignature signature = (MethodSignature)pjp.getSignature();
        String methodName = pjp.getTarget().getClass().getDeclaredMethod(signature.getName(), signature.getParameterTypes()).getName();
        String requestArgs = JSONUtil.toJsonStr(pjp.getArgs());
        // start stopwatch 環繞方法前執行
        Object retVal;
        try {
            retVal = pjp.proceed();
            log.info(className + " | " + methodName + " | "
                    + "請求參數：" + requestArgs + " | "
                    + "返回結果：" + JSONUtil.toJsonStr(retVal));
        } catch(Throwable throwable) {
            log.error(className + " | " + methodName + " | "
                    + "請求參數：" + requestArgs + " | "
                    + "返回結果：" + throwable.getMessage());
            throw throwable;
        }
        return retVal;
    }
}